package com.turbo.cloud.ums.web.logic;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.turbo.cloud.core.exception.BusinessException;
import com.turbo.cloud.core.utils.BeanListUtils;
import com.turbo.cloud.ums.constants.UMSConstants;
import com.turbo.cloud.ums.utils.MenuTreeUtil;
import com.turbo.cloud.ums.web.entity.*;
import com.turbo.cloud.ums.web.model.component.UmsComponentQo;
import com.turbo.cloud.ums.web.model.component.UmsComponentDo;
import com.turbo.cloud.ums.web.model.component.UmsComponentVo;
import com.turbo.cloud.ums.web.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 菜单组件表 逻辑处理类
 * </p>
 *
 * @author zhangluning
 * @since 2022-08-13
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class ComponentLogic {

    final IUmsComponentService umsComponentService;
    final IUmsPermissionComponentRelationService umsRoleComponentRelationService;
    final IUmsMenuService umsMenuService;

    /**
     * 根据菜单ID，查询组件列表
     *
     * @param umsComponentQo 组件实体
     * @return 分页数据
     */
    public List<UmsComponentVo> queryComponentListByMenuId(UmsComponentQo umsComponentQo) {

        // 如果是菜单组，需要把子菜单Id也拿出来
        List<UmsMenu> menuList = umsMenuService.list();
        List<String> menuIds = new ArrayList<>();
        if(!CollectionUtils.isEmpty(menuList)) {
            MenuTreeUtil.getChildrenMenuIds(umsComponentQo.getMenuId(), menuList, menuIds);
        }
        /*
         * 模糊查询条件
         */
        LambdaQueryWrapper<UmsComponent> componentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        componentLambdaQueryWrapper.like(StrUtil.isNotBlank(umsComponentQo.getComponentTitleByLike()),
                UmsComponent::getComponentTitle,
                umsComponentQo.getComponentTitleByLike());

        if(!CollectionUtils.isEmpty(menuIds)) {
            componentLambdaQueryWrapper.in(UmsComponent::getMenuId, menuIds);
        } else {
            componentLambdaQueryWrapper.eq(UmsComponent::getMenuId, umsComponentQo.getMenuId());
        }
        componentLambdaQueryWrapper.orderByAsc(UmsComponent::getSort);

        List<UmsComponent> controlList = umsComponentService.list(componentLambdaQueryWrapper);

        List<UmsComponentVo> controlVoList = new ArrayList<>();
        BeanListUtils.copyList(controlList, controlVoList, UmsComponentVo::new);

        return controlVoList;
    }

    /**
     * 根据菜单ID，查询组件列表，并根据权限ID标记选中
     *
     * @param umsComponentQo 组件实体
     * @return 分页数据
     */
    public List<UmsComponentVo> queryComponentCheckedListByMenuIdOfPermissionId(UmsComponentQo umsComponentQo) {
        List<UmsComponentVo> controlVoList = queryComponentListByMenuId(umsComponentQo);

        /*
         * 根据角色ID获取角色关联的组件ID集合
         */
        LambdaQueryWrapper<UmsPermissionComponentRelation> permissionComponentLQW = new LambdaQueryWrapper<>();
        permissionComponentLQW.eq(UmsPermissionComponentRelation::getPermissionId, umsComponentQo.getPermissionId());
        List<UmsPermissionComponentRelation> roleComponentList = umsRoleComponentRelationService.list(permissionComponentLQW);

        if (!CollectionUtils.isEmpty(controlVoList) && !CollectionUtils.isEmpty(roleComponentList)) {
            List<String> componentIdList = roleComponentList.stream().map(UmsPermissionComponentRelation::getComponentId).toList();
            for (UmsComponentVo umsComponentVo : controlVoList) {
                umsComponentVo.setChecked(componentIdList.contains(umsComponentVo.getId()));
            }
        }

        return controlVoList;
    }

    /**
     * 新增组件
     *
     * @param umsComponentDo 实体
     * @return
     */
    public Boolean createComponent(UmsComponentDo umsComponentDo) {
        UmsComponent umsComponent = new UmsComponent();
        BeanUtils.copyProperties(umsComponentDo, umsComponent);

        boolean result = umsComponentService.save(umsComponent);
        if (!result) {
            throw new BusinessException("新增组件失败");
        }
        return true;
    }

    /**
     * 修改组件
     *
     * @param umsComponentDo 实体
     * @return
     */
    public Boolean modifyComponent(UmsComponentDo umsComponentDo) {
        if (StrUtil.isBlank(umsComponentDo.getId())) {
            throw new BusinessException("组件ID不能为空");
        }
        UmsComponent umsComponent = new UmsComponent();
        BeanUtils.copyProperties(umsComponentDo, umsComponent);

        boolean result = umsComponentService.updateById(umsComponent);
        if (!result) {
            throw new BusinessException("修改组件失败");
        }
        return true;
    }

    /**
     * 开启、关闭组件有效状态
     *
     * @param id 权限ID
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean enabledComponentStateById(String id) {
        UmsComponent umsComponent = umsComponentService.getById(id);
        if (Objects.isNull(umsComponent)) {
            throw new BusinessException("组件不存在");
        }

        if (UMSConstants.DICT_STATE_ID_YES.equals(umsComponent.getStateId())) {
            umsComponent.setStateId(0);
        } else {
            umsComponent.setStateId(1);
        }

        boolean result = umsComponentService.updateById(umsComponent);
        if (!result) {
            throw new BusinessException("修改组件状态失败");
        }
        return true;
    }

    /**
     * 删除组件
     *
     * @param id 组件ID
     * @return
     */
    public boolean removeComponentById(String id) {
        if (StrUtil.isBlank(id)) {
            throw new BusinessException("组件ID不能为空");
        }

        boolean result = umsComponentService.removeById(id);
        if (!result) {
            throw new BusinessException("修改组件失败");
        }
        return true;
    }
}
